/*******************************************************************************
 * Copyright (c) 2013 Chris Banes.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package net.cardgame.oraclecard.common;

import java.io.InputStream;
import java.lang.ref.WeakReference;

import jp.jma.oraclecard.MyApplication;
import net.cardgame.orcalecard.utils.FileUtils;
import uk.co.senab.bitmapcache.BitmapLruCache;
import uk.co.senab.bitmapcache.CacheableBitmapDrawable;
import uk.co.senab.bitmapcache.CacheableImageView;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * Simple extension of CacheableImageView which allows downloading of Images of
 * the Internet.
 * 
 * This code isn't production quality, but works well enough for this sample.s
 * 
 * @author Chris Banes
 */
public class BitmapCacheableImageView extends CacheableImageView {

	/**
	 * This task simply fetches an Bitmap from the specified URL and wraps it in
	 * a wrapper. This implementation is NOT 'best practice' or production ready
	 * code.
	 */

	private static class ImageUrlAsyncTask extends
			AsyncTask<String, Void, CacheableBitmapDrawable> {

		private final BitmapLruCache mCache;

		private final WeakReference<ImageView> mImageViewRef;

		private final BitmapFactory.Options mDecodeOpts;

		ImageUrlAsyncTask(ImageView imageView, BitmapLruCache cache,
				BitmapFactory.Options decodeOpts) {
			mCache = cache;
			mImageViewRef = new WeakReference<ImageView>(imageView);
			mDecodeOpts = decodeOpts;
		}

		@Override
		protected CacheableBitmapDrawable doInBackground(String... params) {
			// Return early if the ImageView has disappeared.
			if (null == mImageViewRef.get()) {
				return null;
			}

			final String sourcePath = params[0];

			// Now we're not on the main thread we can check all caches
			CacheableBitmapDrawable result = mCache.getFromDiskCache(params[0],
					mDecodeOpts);
			try {

				if (null == result) {
					InputStream is = FileUtils.decrytToInputStream(sourcePath);
					// Add to cache
					result = mCache.put(sourcePath, is, mDecodeOpts, true);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
			return result;

		}

		@Override
		protected void onPostExecute(CacheableBitmapDrawable result) {
			super.onPostExecute(result);

			ImageView iv = mImageViewRef.get();
			if (null != iv) {
				iv.setImageDrawable(result);
			}
		}
	}

	private BitmapLruCache mCache;

	private ImageUrlAsyncTask mCurrentTask;
	float rotate = 0;
	Context context;

	public BitmapCacheableImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mCache = MyApplication.getInstance().getBitmapCache();
		this.context = context;
	}

	public boolean loadImage(String sourcePath, Context context, float rotate) {
		this.rotate = rotate;
		// First check whether there's already a task running, if so cancel it
		if (null != mCurrentTask) {
			mCurrentTask.cancel(true);
		}
		// Check to see if the memory cache already has the bitmap. We can
		// safely do
		// this on the main thread.
		BitmapDrawable wrapper = mCache.getFromMemoryCache(sourcePath);
		BitmapFactory.Options option = new BitmapFactory.Options();
		option.outHeight = this.getHeight();
		option.outWidth = this.getWidth();
		if (null != wrapper) {
			// The cache has it, so just display it
			setImageDrawable(wrapper);
			return true;
		} else {
			// Memory Cache doesn't have the URL, do threaded request...
			setImageDrawable(null);
			mCurrentTask = new ImageUrlAsyncTask(this, mCache, option);
			mCurrentTask.execute(sourcePath);
			// ThreadLoadImage thread = new ThreadLoadImage(sourcePath, option,
			// mCache);
			// thread.start();
			return false;

		}
	}

}
